package com.spring.demo8.eg2;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;

/**
 * @author vhans
 */
public class Test {
    @org.junit.Test
    public void test1() {
        // 定义一个spring容器，这个容器默认实现了BeanDefinitionRegistry，所以其本身就是一个bean注册器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

        // 定义一个xml的BeanDefinition读取器，需要传入一个Bean注册器
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);

        String location = "classpath:/xml/demo8/compositeObj.xml";
        // 通过xmlBeanDefinitionReader加载xml文件，并且将解析产生的BeanDefinition注册到容器中
        int countBean = xmlBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.printf("共注册了 %s 个bean\n", countBean);
        print(factory);
    }

    @org.junit.Test
    public void test2() {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(factory);

        String location = "classpath:/xml/demo8/beans.properties";
        int countBean = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.printf("共注册了 %s 个bean\n", countBean);
        print(factory);
    }

    @org.junit.Test
    public void test3() {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);
        // 根据类型进行注册
        annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
        // 加上这一行后Service2中的Service1才被真正注入，不然为空
        factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
        print(factory);
    }

    private void print(DefaultListableBeanFactory factory) {
        // 打印注册的bean的配置信息
        for (String beanName : factory.getBeanDefinitionNames()) {
            // 通过名称从容器中获取对应的BeanDefinition信息
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            // 获取BeanDefinition具体使用哪个类
            String beanDefinitionClassName = beanDefinition.getClass().getName();
            // 通过名称获取bean对象
            Object bean = factory.getBean(beanName);

            System.out.println(beanName + ":");
            System.out.println("  beanDefinition: " + beanDefinition);
            System.out.println("  beanDefinitionClassName: " + beanDefinitionClassName);
            System.out.println("  bean: " + bean);
        }
    }
}
